package com.franklin.ideaplugin.easytesting.common.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.StrUtil;
import com.franklin.ideaplugin.easytesting.common.entity.MethodInvokeData;
import com.franklin.ideaplugin.easytesting.common.entity.MethodParameter;
import com.franklin.ideaplugin.easytesting.common.resolver.IMethodParameterResolver;
import com.franklin.ideaplugin.easytesting.common.resolver.MethodParameterResolverFactory;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author Ye Junhui
 * @since 2023/5/15
 */
public class MethodUtils extends ReflectionUtils {

    /**
     * 判断方法是否是静态方法
     * @param method
     * @return
     */
    public static boolean isStaticMethod(Method method){
        return Modifier.isStatic(method.getModifiers());
    }

    /**
     * 解析参数类型
     * @param methodInvokeData
     * @return
     */
    public static Class<?>[] resolveParamTypes(MethodInvokeData methodInvokeData){
        //参数类型
        LinkedHashMap<String, MethodParameter> parameterMap = methodInvokeData.getParameterMap();
        if (CollectionUtil.isEmpty(parameterMap)){
            return new Class<?>[]{};
        }
        Class<?>[] paramTypes = parameterMap.values().stream()
                .map(methodParameter -> {
                    IMethodParameterResolver resolver = MethodParameterResolverFactory.getResolver(methodParameter);
                    if (Objects.isNull(resolver)){
                        return null;
                    }
                    return resolver.resolveType(methodParameter);
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList())
                .toArray(new Class<?>[]{});
        return paramTypes;
    }

    /**
     * 解析数据
     * @param methodParameter
     * @return
     */
    public static Object parseValue(MethodParameter methodParameter){
        IMethodParameterResolver resolver = MethodParameterResolverFactory.getResolver(methodParameter);
        if (Objects.isNull(resolver)){
            return null;
        }
        return resolver.resolveValue(methodParameter);
    }

    /**
     * 获取脚本类名
     * @param classQualifiedName
     * @param methodName
     * @return
     */
    public static String getScriptClassName(String classQualifiedName,String methodName){
        if (StrUtil.isBlank(methodName)){
            return "";
        }
        String className = StrUtil.upperFirst(methodName);
        if (StrUtil.isBlank(classQualifiedName)){
            return className;
        }
        String[] packageNameArr = classQualifiedName.split("\\.");
        String simpleName = packageNameArr[packageNameArr.length - 1];
        String packageShortName = Arrays.stream(packageNameArr)
                .filter(packageName -> !packageName.equals(simpleName))
                .map(String::toUpperCase)
                .map(packageName -> packageName.charAt(0))
                .map(String::valueOf)
                .collect(Collectors.joining());
        className = packageShortName + "$" + className;
        return className;
    }
}
